home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 6 / CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso / cucd / online / fidonetts / yoohoo.c < prev   
C/C++ Source or Header  |  1991-09-16  |  40KB  |  1,076 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                     BinkleyTerm "YooHoo" Processor                       */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491             */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*                                                                          */
  45. /*--------------------------------------------------------------------------*/
  46.  
  47. /* Include this file before any other includes or defines! */
  48.  
  49. #include "includes.h"
  50.  
  51.  
  52. int Send_Hello_Packet (int);
  53. int Recv_Hello_Packet (int);
  54.  
  55. /*
  56.  * Data structure used by all YooHoo state machine functions.
  57.  * Contains all data which needs to be passed between various states.
  58.  *
  59.  */
  60.  
  61. typedef struct {
  62.    long timer1;                         /* Outermost timer                  */
  63.    long timer2;                         /* Next inner timer                 */
  64.    long timer3;                         /* Next inner timer                 */
  65.    struct _Hello Hello;                 /* Data packet                      */
  66.    word crc;                            /* CRC of data packet               */
  67.    word hiscrc;                         /* other's CRC of data packet       */
  68.    int sender;                          /* Set to 1 if we're calling him    */
  69.    int result;                          /* Result we want to send out       */
  70.    int retries;                         /* Number of retries                */
  71.    int count;                           /* Number of characters received    */
  72. } YHARGS, *YHARGSP;
  73.  
  74. int YRInit (YHARGSP, int);              /* Called by state machine at start */
  75. int YRExit (YHARGSP, int);              /* Called by state machine at end   */
  76. int YRGetHello (YHARGSP);               /* YR1 state processing function    */
  77. int YRWaitResp (YHARGSP);               /* YR2 state processing function    */
  78. int YRPollPeer (YHARGSP);               /* YR3 state processing function    */
  79. int YRSndHello (YHARGSP);               /* YR4 state processing function    */
  80.  
  81. int YSInit (YHARGSP, int);              /* Called by state machine at start */
  82. int YSExit (YHARGSP, int);              /* Called by state machine at end   */
  83. int YSSndHello (YHARGSP);               /* YS1 state processing function    */
  84. int YSWaitResp (YHARGSP);               /* YS2 state processing function    */
  85. int YSGetHello (YHARGSP);               /* YS3 state processing function    */
  86.  
  87. int SHInit (YHARGSP, int);              /* Called by state machine at start */
  88. int SHExit (YHARGSP, int);              /* Called by state machine at end   */
  89. int SHInitSend (YHARGSP);               /* SH1 state processing function    */
  90. int SHSendHedr (YHARGSP);               /* SH2 state processing function    */
  91. int SHSendCRC (YHARGSP);                /* SH3 state processing function    */
  92. int SHGetResp (YHARGSP);                /* SH4 state processing function    */
  93.  
  94. int RHInit (YHARGSP, int);              /* Called by state machine at start */
  95. int RHExit (YHARGSP, int);              /* Called by state machine at end   */
  96. int RHSendENQ (YHARGSP);                /* RH1 state processing function    */
  97. int RHWaitHedr (YHARGSP);               /* RH2 state processing function    */
  98. int RHTossJunk (YHARGSP);               /* RH3 state processing function    */
  99. int RHReSynch (YHARGSP);                /* RH4 state processing function    */
  100. int RHHdrSetup (YHARGSP);               /* RH5 state processing function    */
  101. int RHGetHChar (YHARGSP);               /* RH6 state processing function    */
  102. int RHStoHChar (YHARGSP);               /* RH7 state processing function    */
  103. int RHCheckCRC (YHARGSP);               /* RH8 state processing function    */
  104. int RHCountERR (YHARGSP);               /* RH9 state processing function    */
  105. int RHHelloOK (YHARGSP);                /* RH10 state processing function   */
  106.  
  107. #define YR0    0                        /* Reserved value of 0 for init     */
  108. #define YRexit 0                        /* Slot 1 is exit, but called by 0  */
  109. #define YR1    2                        /* First "user" slot is 2.          */
  110. #define YR2    3                        /* After that, it all maps n : n+1  */
  111. #define YR3    4
  112. #define YR4    5
  113.  
  114. #define YS0    0                        /* Reserved value of 0 for init     */
  115. #define YSexit 0                        /* Slot 1 is exit, but called by 0  */
  116. #define YS1    2                        /* First "user" slot is 2.          */
  117. #define YS2    3                        /* After that, it all maps n : n+1  */
  118. #define YS3    4
  119.  
  120. #define SH0    0                        /* Reserved value of 0 for init     */
  121. #define SHexit 0                        /* Slot 1 is exit, but called by 0  */
  122. #define SH1    2                        /* First "user" slot is 2.          */
  123. #define SH2    3                        /* After that, it all maps n : n+1  */
  124. #define SH3    4
  125. #define SH4    5
  126.  
  127. #define RH0    0                        /* Reserved value of 0 for init     */
  128. #define RHexit 0                        /* Slot 1 is exit, but called by 0  */
  129. #define RH1    2                        /* First "user" slot is 2.          */
  130. #define RH2    3                        /* After that, it all maps n : n+1  */
  131. #define RH3    4
  132. #define RH4    5
  133. #define RH5    6
  134. #define RH6    7
  135. #define RH7    8
  136. #define RH8    9
  137. #define RH9    10
  138. #define RH10   11
  139.  
  140. STATES YooHoo_Rcvr [] = {               /* Table used by state machine      */
  141.    { "YRInit",     YRInit     },        /* And referred to by 'YRn' defines */
  142.    { "YRExit",     YRExit     },        /* listed above ...                 */
  143.    { "YRGetHello", YRGetHello },
  144.    { "YRWaitResp", YRWaitResp },
  145.    { "YRPollPeer", YRPollPeer },
  146.    { "YRSndHello", YRSndHello },
  147. };
  148.  
  149. STATES YooHoo_Sndr [] = {               /* Table used by state machine      */
  150.    { "YSInit",     YSInit     },        /* And referred to by 'YRn' defines */
  151.    { "YSExit",     YSExit     },        /* listed above ...                 */
  152.    { "YSSndHello", YSSndHello },
  153.    { "YSWaitResp", YSWaitResp },
  154.    { "YSGetHello", YSGetHello },
  155. };
  156.  
  157. STATES Snd_Hello [] = {                 /* Table used by state machine      */
  158.    { "SHInit",     SHInit     },        /* And referred to by 'SHn' defines */
  159.    { "SHExit",     SHExit     },        /* listed above ...                 */
  160.    { "SHInitSend", SHInitSend },
  161.    { "SHSendHedr", SHSendHedr },
  162.    { "SHSendCRC",  SHSendCRC  },
  163.    { "SHGetResp",  SHGetResp  },
  164. };
  165.  
  166. STATES Rcv_Hello [] = {                 /* Table used by state machine      */
  167.    { "RHInit",      RHInit     },       /* And referred to by 'RHn' defines */
  168.    { "RHExit",      RHExit     },       /* listed above ...                 */
  169.    { "RHSendENQ",   RHSendENQ  },
  170.    { "RHWaitHedr",  RHWaitHedr },
  171.    { "RHTossJunk",  RHTossJunk },
  172.    { "RHReSynch",   RHReSynch  },
  173.    { "RHHdrSetup",  RHHdrSetup },
  174.    { "RHGetHChar",  RHGetHChar },
  175.    { "RHStoHChar",  RHStoHChar },
  176.    { "RHCheckCRC",  RHCheckCRC },
  177.    { "RHCountERR",  RHCountERR },
  178.    { "RHHelloOK",   RHHelloOK  },
  179. };
  180.  
  181. /*--------------------------------------------------------------------------*/
  182. /* YOOHOO SENDER    (used when I am the CALLING system)                     */
  183. /*--------------------------------------------------------------------------*/
  184. int YooHoo_Sender (void)
  185. {
  186.    YHARGS args;
  187.    int res;
  188.  
  189.    args.result = 0;
  190.  
  191.    res = state_machine (YooHoo_Sndr, &args, 2);
  192.    return (res);
  193. }
  194.  
  195.  
  196. int YSInit (YHARGSP args, int start_state)
  197. {
  198.  
  199.     if (un_attended && fullscreen)
  200.         {
  201.         sb_move (file_hWnd, 2, 2);
  202.         FlLnModeSet (FILE_LN_2, 0);
  203.         sb_puts (GetDlgItem (file_hWnd, FILE_LN_2), "YooHoo");
  204.         sb_show ();
  205.         }
  206.     else
  207.         {
  208.         set_xy ("YooHoo ");
  209.         }
  210.  
  211.    /*--------------------------------------------------------------------*/
  212.    /* Clean up any mess that may be around                               */
  213.    /*--------------------------------------------------------------------*/
  214.  
  215.     CLEAR_OUTBOUND ();
  216.     CLEAR_INBOUND ();
  217.     XON_DISABLE ();
  218.  
  219.     happy_compiler = args->result + start_state;
  220.    
  221.     return (YS1);
  222. }
  223.  
  224. /*
  225.  * This routine is called by the state machine when the '??exit'
  226.  * state is seen. Its return value is what the state machine
  227.  * will return to its caller as the result of the function.
  228.  *
  229.  */
  230.  
  231. int YSExit (YHARGSP args, int cur_state)
  232. {
  233.     happy_compiler = cur_state;  /* Makes the compiler happy! */
  234.     return (args->result);
  235. }
  236. /*
  237.  .-----+----------+-------------------------+-------------------------+-----.
  238.  | YS1 | SndHello | Successful              | Looks like WaZOO        | YS2 |
  239.  |     | (state   +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  240.  |     |  SH1)    | Not successful          | Repeat whole thing      | exit|
  241.  `-----+----------+-------------------------+-------------------------+-----'
  242. */
  243. int YSSndHello (YHARGSP args)
  244. {
  245.     if (!Send_Hello_Packet (1))
  246.         {
  247.         status_line (MSG_TXT(M_HE_HUNG_UP));
  248.         return (YSexit);
  249.         }
  250.  
  251.     happy_compiler = args->result;
  252.     return (YS2);
  253. }
  254. /*
  255.  .-----+----------+-------------------------+-------------------------+-----.
  256.  | YS2 | WaitResp | 30 sec timer expires    | repeat whole thing      | exit|
  257.  |     |          | or lost carrier         |                         |     |
  258.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  259.  |     |          | Received YOOHOO         | Another WaZOO, go       | YS3 |
  260.  |     |          |                         | process receive         |     |
  261.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  262.  |     |          | Received debris         | Repeat whole thing      | YS2 |
  263.  `-----+----------+-------------------------+-------------------------+-----'
  264. */
  265. int YSWaitResp (YHARGSP args)
  266. {
  267.     long resp_timer = timerset (3000);
  268.  
  269.     while (TIMED_READ (5) != YOOHOO)
  270.         {
  271.         if (timeup (resp_timer))
  272.             {
  273.             status_line ("!No YOOHOO/2U2");
  274.             status_line (IDUNNO_msg);
  275.             return (YSexit);
  276.             }
  277.         }
  278.  
  279.     happy_compiler = args->result;
  280.     return (YS3);
  281. }
  282. /*
  283.  .-----+----------+-------------------------+-------------------------+-----.
  284.  | YS3 | GetHello | Information             | Report Success          | exit|
  285.  |     | (state   | Successfully            |                         |     |
  286.  |     |  RH1)    | Exchanged               |                         |     |
  287.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  288.  |     |          | Failure                 | Repeat whole thing      | exit|
  289.  `-----+----------+-------------------------+-------------------------+-----'
  290. */
  291. int YSGetHello (YHARGSP args)
  292. {
  293.     args->result = Recv_Hello_Packet (1);
  294.     return (YSexit);
  295. }
  296.  
  297.  
  298.  
  299. /*--------------------------------------------------------------------------*/
  300. /* YOOHOO RECEIVER  (Used when I am the CALLED system)                      */
  301. /*--------------------------------------------------------------------------*/
  302.  
  303. int YooHoo_Receiver (void)
  304. {
  305.     YHARGS args;
  306.     int res;
  307.  
  308.     args.result = 0;
  309.  
  310.     res = state_machine (YooHoo_Rcvr, &args, 2);
  311.     return (res);
  312. }
  313.  
  314. int YRInit (YHARGSP args, int start_state)
  315. {
  316.  
  317.     if (un_attended && fullscreen)
  318.         {
  319.         sb_move (file_hWnd, 2, 2);
  320.         FlLnModeSet (FILE_LN_2, 0);
  321.         sb_puts (GetDlgItem (file_hWnd, FILE_LN_2), "YooHoo");
  322.         sb_show ();
  323.         }
  324.     else
  325.         {
  326.         set_xy ("YooHoo ");
  327.         }
  328.  
  329.    /*--------------------------------------------------------------------*/
  330.    /* Clean up any mess that may be around                               */
  331.    /*--------------------------------------------------------------------*/
  332.  
  333.     CLEAR_OUTBOUND ();
  334.     CLEAR_INBOUND ();
  335.     XON_DISABLE ();
  336.  
  337.     happy_compiler = args->result + start_state;
  338.  
  339.     return (YR1);
  340. }
  341.  
  342. /*
  343.  * This routine is called by the state machine when the '??exit'
  344.  * state is seen. Its return value is what the state machine
  345.  * will return to its caller as the result of the function.
  346.  *
  347.  */
  348.  
  349. int YRExit (YHARGSP args, int cur_state)
  350. {
  351.     happy_compiler = cur_state;  /* Makes the compiler happy! */
  352.     return (args->result);
  353. }
  354. /*
  355.  .-----+----------+-------------------------+-------------------------+-----.
  356.  | YR1 | GetHello | Information             | Start 20 sec timer      | YR2 |
  357.  |     | (state   | Successfully            | Initialize retry count  |     |
  358.  |     |  RH1)    | Exchanged               | Send YooHoo             |     |
  359.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  360.  |     |          | Failure                 | Repeat whole thing      | exit|
  361.  `-----+----------+-------------------------+-------------------------+-----'
  362. */
  363. int YRGetHello (YHARGSP args)
  364. {
  365.     if (Recv_Hello_Packet(0) == 0)
  366.         return (YRexit);
  367.     args->timer1 = timerset (2000);
  368.     args->retries = 0;
  369.     SENDBYTE (YOOHOO);
  370.     return (YR2);
  371. }
  372. /*
  373.  .-----+----------+-------------------------+-------------------------+-----.
  374.  | YR2 | WaitResp | 20 sec timeout          | try again               | YR3 |
  375.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  376.  |     |          | Lost carrier            | Failure                 | exit|
  377.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  378.  |     |          | Received ENQ            | Go send hello           | YR4 |
  379.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  380.  |     |          | Received debris         | Keep looking            | YR2 |
  381.  `-----+----------+-------------------------+-------------------------+-----'
  382. */
  383. int YRWaitResp (YHARGSP args)
  384. {
  385.     while (TIMED_READ (5) != ENQ)
  386.         {
  387.         if (!CARRIER)
  388.             {
  389.             status_line (MSG_TXT(M_NO_CARRIER));
  390.             return (YRexit);
  391.             }
  392.         if (timeup (args->timer1))
  393.             return (YR3);
  394.         }
  395.     return (YR4);
  396. }
  397. /*
  398.  .-----+----------+-------------------------+-------------------------+-----.
  399.  | YR3 | PollPeer | More than 3 retries     | Give it up              | exit|
  400.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  401.  |     |          | Less than 3 retries     | Bump retry count        | YR2 |
  402.  |     |          |                         | Clear input buffer      |     |
  403.  |     |          |                         | Send YOOHOO             |     |
  404.  |     |          |                         | Restart 20 sec timer    |     |
  405.  `-----+----------+-------------------------+-------------------------+-----'
  406. */
  407. int YRPollPeer (YHARGSP args)
  408. {
  409.     if (++(args->retries) > 3)
  410.         {
  411.         status_line (MSG_TXT(M_FUBAR_MSG));
  412.         b_init ();
  413.         return (YRexit);
  414.         }
  415.  
  416.     CLEAR_INBOUND ();
  417.     SENDBYTE (YOOHOO);
  418.     args->timer1 = timerset (2000);
  419.     return (YR2);
  420. }
  421. /*
  422.  .-----+----------+-------------------------+-------------------------+-----.
  423.  | YR4 | SndHello | Successful              | All done, report success| exit|
  424.  |     | (state   +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  425.  |     |  SH1)    | Not successful          | Repeat whole thing      | exit|
  426.  `-----+----------+-------------------------+-------------------------+-----'
  427. */
  428. int YRSndHello (YHARGSP args)
  429. {
  430.     if ((args->result = Send_Hello_Packet (0)) == 0)
  431.         b_init ();
  432.     return (YRexit);
  433. }
  434.  
  435.  
  436. /*--------------------------------------------------------------------------*/
  437. /* SEND HELLO PACKET                                                        */
  438. /*--------------------------------------------------------------------------*/
  439. int Send_Hello_Packet (int Sender)
  440. {
  441.    YHARGS args;
  442.    int res;
  443.  
  444.    args.result = 0;
  445.    args.sender = Sender;
  446.  
  447.    res = state_machine (Snd_Hello, &args, 2);
  448.    return (res);
  449. }
  450.  
  451. int SHInit (YHARGSP args, int start_state)
  452. {
  453.     happy_compiler = args->result + start_state;
  454.    
  455.     return (SH1);
  456. }
  457.  
  458. /*
  459.  * This routine is called by the state machine when the '??exit'
  460.  * state is seen. Its return value is what the state machine
  461.  * will return to its caller as the result of the function.
  462.  *
  463.  */
  464.  
  465. int SHExit (YHARGSP args, int cur_state)
  466. {
  467.     happy_compiler = cur_state;  /* Makes the compiler happy! */
  468.     return (args->result);
  469. }
  470.  
  471. /*
  472.  .-----+----------+-------------------------+-------------------------+-----.
  473.  | SH1 | InitSend |                         | Disable XON/XOFF        | SH2 |
  474.  |     |          |                         | Set retry count to 0    |     |
  475.  `-----+----------+-------------------------+-------------------------+-----'
  476. */
  477. int SHInitSend (YHARGSP args)
  478. {
  479.  
  480.    XON_DISABLE ();
  481.    args->retries = 0;
  482.  
  483.    return (SH2);
  484. }
  485. /*
  486.  .-----+----------+-------------------------+-------------------------+-----.
  487.  | SH2 | SendHedr |                         | Send Hex 1f, then       | SH3 |
  488.  |     |          |                         | Send HELLO struct       |     |
  489.  `-----+----------+-------------------------+-------------------------+-----'
  490. */
  491. int SHSendHedr (YHARGSP args)
  492. {
  493.     word can_do_domain = 0;
  494.     word crc;
  495.     char *sptr;
  496.     int i;
  497.  
  498.    /*--------------------------------------------------------------------*/
  499.    /* Setup HELLO structure                                              */
  500.    /*--------------------------------------------------------------------*/
  501.  
  502.     (void) memset ((char *) &args->Hello, 0, sizeof (struct _Hello));
  503.  
  504.     args->Hello.signal = 'o';
  505.     args->Hello.hello_version = 1;
  506.  
  507.     args->Hello.product = PRDCT_CODE;
  508.     args->Hello.product_maj = BINK_MAJVERSION;
  509.     args->Hello.product_min = BINK_MINVERSION;
  510.  
  511.     (void) strncpy (args->Hello.sysop, sysop, 19);
  512.     args->Hello.sysop[19] = '\0';
  513.  
  514.     args->Hello.my_zone = alias[assumed].Zone;
  515.     if ((pvtnet >= 0) && (args->sender) &&
  516.         ((called_addr.Zone == boss_addr.Zone) || (called_addr.Zone == 0) || (boss_addr.Zone == 0)) &&
  517.         (called_addr.Net == boss_addr.Net) && (called_addr.Node == boss_addr.Node) &&
  518.         ((called_addr.Domain == boss_addr.Domain) || (boss_addr.Domain == NULL) || (called_addr.Domain == NULL)))
  519.         {
  520.         args->Hello.my_net = boss_addr.Net;
  521.         args->Hello.my_node = boss_addr.Node;
  522.         args->Hello.my_point = alias[assumed].Node;
  523.         }
  524.     else
  525.         {
  526.         args->Hello.my_net = alias[assumed].Net;
  527.         args->Hello.my_node = alias[assumed].Node;
  528.         args->Hello.my_point = alias[assumed].Point;
  529.         }
  530. /*
  531.  * If we are the calling system, turn on all our capabilities.
  532.  * If we are the called system, choose from the set that the
  533.  * caller gave us, and only send the one we prefer.
  534.  */
  535.     can_do_domain = (my_addr.Domain != NULL) ? DO_DOMAIN : 0;
  536.     if (args->sender == 0)
  537.         {
  538.         can_do_domain = remote_capabilities & can_do_domain;
  539.         if (remote_capabilities & my_capabilities & DOES_IANUS)
  540.             args->Hello.capabilities = DOES_IANUS;
  541.         else if (remote_capabilities & my_capabilities & ZED_ZAPPER)
  542.             args->Hello.capabilities = ZED_ZAPPER;
  543.         else if (remote_capabilities & my_capabilities & ZED_ZIPPER)
  544.             args->Hello.capabilities = ZED_ZIPPER;
  545.         else if (remote_capabilities & my_capabilities & Y_DIETIFNA)
  546.             args->Hello.capabilities = Y_DIETIFNA;
  547.         }
  548.     else args->Hello.capabilities = my_capabilities;
  549.  
  550.     (void) strncpy (args->Hello.my_name, system_name, 58);
  551.     args->Hello.my_name[58] = '\0';
  552.     args->Hello.capabilities |= can_do_domain;
  553.     if (can_do_domain && (alias[assumed].Domain != NULL))
  554.         {
  555.         if (strlen (system_name) + strlen (alias[assumed].Domain) > 57)
  556.             {
  557.             args->Hello.my_name[57 - strlen (alias[assumed].Domain)] = '\0';
  558.             }
  559.         sptr = args->Hello.my_name + strlen (args->Hello.my_name) + 1;
  560.         (void) strcpy (sptr, alias[assumed].Domain);
  561.         }
  562.  
  563.     if (n_getpassword (&remote_addr))
  564.         {
  565.         (void) strncpy ((char *)(args->Hello.my_password), remote_password, 8);
  566.         }
  567.  
  568.     if ((matrix_mask & TAKE_REQ) &&
  569.        ((args->sender == 0) || (on_our_nickel)))
  570.         args->Hello.capabilities |= WZ_FREQ;
  571.  
  572.  
  573.    /*--------------------------------------------------------------------*/
  574.    /* Send the packet.                                                   */
  575.    /* Load outbound buffer quickly, and get modem busy sending.          */
  576.    /*--------------------------------------------------------------------*/
  577.  
  578.     SENDBYTE (0x1f);
  579.     sptr = (char *) (&args->Hello);
  580.     SENDCHARS (sptr, 128, 1);
  581.  
  582.    /*--------------------------------------------------------------------*/
  583.    /* Calculate CRC while modem is sending its buffer                    */
  584.    /*--------------------------------------------------------------------*/
  585.  
  586.     for (crc = i = 0; i < 128; i++)
  587.         {
  588.         crc = xcrc (crc, (byte) sptr[i]);
  589.         }
  590.  
  591.     args->crc = crc;
  592.     return (SH3);
  593. }
  594. /*
  595.  .-----+----------+-------------------------+-------------------------+-----.
  596.  | SH3 | SendCRC  |                         | Clear Input Buffer      | SH4 |
  597.  |     |          |                         | Send two-byte CRC of pkt|     |
  598.  |     |          |                         | MSB followed by LSB     |     |
  599.  |     |          |                         | Start 40 second timer   |     |
  600.  `-----+----------+-------------------------+-------------------------+-----'
  601. */
  602. SHSendCRC (YHARGSP args)
  603. {
  604.     CLEAR_INBOUND ();
  605.  
  606.     SENDBYTE ((unsigned char) (args->crc >> 8));
  607.     SENDBYTE ((unsigned char) (args->crc & 0xff));
  608.  
  609.     args->timer1 = timerset (4000);
  610.     return (SH4);
  611. }
  612. /*
  613.  .-----+----------+-------------------------+-------------------------+-----.
  614.  | SH4 | GetResp  | 40 second timer expires | Failed to send packet   | exit|
  615.  |     |          | or carrier lost         |                         |     |
  616.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  617.  |     |          | ACK received            | Successful transmission | exit|
  618.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  619.  |     |          | '?' received            | Error, try retransmit   | SH2 |
  620.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  621.  |     |          | ENQ received            | Out of sync?            | SH2 |
  622.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  623.  |     |          | other character recvd   | Debris, keep watching   | SH4 |
  624.  `-----+----------+-------------------------+-------------------------+-----'
  625. */
  626. SHGetResp (YHARGSP args)
  627. {
  628.     int i;
  629.     char junkbuff [80];
  630.  
  631.     while ((i = TIMED_READ (5)) != ACK)
  632.         {
  633.         if (timeup (args->timer1))
  634.             {
  635.             (void) sprintf (junkbuff, "!%s",MSG_TXT(M_TIMEOUT));
  636.             status_line (junkbuff);
  637.             return (SHexit);
  638.             }
  639.  
  640.         if (!CARRIER)
  641.             {
  642.             status_line (MSG_TXT(M_NO_CARRIER));
  643.             return (SHexit);
  644.             }
  645.  
  646.         if (got_ESC ())
  647.             {
  648.             LOWER_DTR ();
  649.             status_line (MSG_TXT(M_KBD_MSG));
  650.             return (SHexit);
  651.             }
  652.  
  653.         switch (i)
  654.             {
  655.             case '?':
  656.             status_line (MSG_TXT(M_DRATS));
  657.  
  658.             case ENQ:
  659.             if (++(args->retries) == 10)
  660.                 {
  661.                 status_line (MSG_TXT(M_FUBAR_MSG));
  662.                 return (SHexit);
  663.                 }
  664.             CLEAR_INBOUND ();
  665.             return (SH2);
  666.             default:
  667.             break;
  668.             }
  669.         }
  670.  
  671.    args->result = 1;
  672.    return (SHexit);
  673. }
  674.  
  675.  
  676.  
  677. /*--------------------------------------------------------------------------*/
  678. /* RECEIVE HELLO PACKET                                                     */
  679. /*--------------------------------------------------------------------------*/
  680. int Recv_Hello_Packet (int Sender)
  681. {
  682.    YHARGS args;
  683.    int res;
  684.  
  685.    args.result = 0;
  686.    args.sender = Sender;
  687.  
  688.    res = state_machine (Rcv_Hello, &args, 2);
  689.    return (res);
  690. }
  691.  
  692. int RHInit (YHARGSP args, int start_state)
  693. {
  694.     happy_compiler = args->result + start_state;
  695.    
  696.     return (RH1);
  697. }
  698.  
  699. /*
  700.  * This routine is called by the state machine when the '??exit'
  701.  * state is seen. Its return value is what the state machine
  702.  * will return to its caller as the result of the function.
  703.  *
  704.  */
  705.  
  706. int RHExit (YHARGSP args, int cur_state)
  707. {
  708.     happy_compiler = cur_state;  /* Makes the compiler happy! */
  709.     if (args->result == 0)
  710.         b_init ();
  711.     return (args->result);
  712. }
  713. /*
  714.  .-----+----------+-------------------------+-------------------------+-----.
  715.  | RH1 | SendENQ  |                         | Start 2 minute timer    | RH2 |
  716.  |     |          |                         | Send an ENQ character   |     |
  717.  `-----+----------+-------------------------+-------------------------+-----'
  718. */
  719. int RHSendENQ (YHARGSP args)
  720. {
  721.     if (un_attended && fullscreen)
  722.         {
  723.         sb_move (file_hWnd, 2, 2);
  724.         FlLnModeSet (FILE_LN_2, 0);
  725.         sb_puts (GetDlgItem (file_hWnd, FILE_LN_2), "YooHoo/2U2");
  726.         sb_show ();
  727.         }
  728.     else
  729.         {
  730.         set_xy ("YooHoo/2U2 ");
  731.         }
  732.  
  733.     SENDBYTE (ENQ);                              /* Let the other system know
  734.                                                   * we heard YooHoo. */
  735.  
  736.     args->timer1 = timerset (12000);             /* No more than 2 mins! */
  737.     args->timer2 = 0L;
  738.     args->retries = 0;
  739.     return (RH2);
  740. }
  741. /*
  742.  .-----+----------+-------------------------+-------------------------+-----.
  743.  | RH2 | WaitHedr | 2 minute timer expires  | Report failure          | exit|
  744.  |     |          | or carrier lost         |                         |     |
  745.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  746.  |     |          | Received Hex 1f         | Got header, get packet  | RH5 |
  747.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  748.  |     |          | Received other char     | Debris, throw away      | RH3 |
  749.  |     |          |                         | Start 10 sec timer      |     |
  750.  `-----+----------+-------------------------+-------------------------+-----'
  751. */
  752. int RHWaitHedr (YHARGSP args)
  753. {
  754.     int i;
  755.     char junkbuff [80];
  756.  
  757.     while ((i = TIMED_READ (5)) != 0x1f)
  758.         {
  759.         if (!CARRIER)
  760.             {
  761.             status_line (MSG_TXT(M_NO_CARRIER));
  762.             return (RHexit);
  763.             }
  764.  
  765.         if (got_ESC ())
  766.             {
  767.             status_line (MSG_TXT(M_KBD_MSG));
  768.             return (RHexit);
  769.             }
  770.  
  771.         if (timeup (args->timer1))
  772.             {
  773.             (void) sprintf (junkbuff, "!%s",MSG_TXT(M_TIMEOUT));
  774.             status_line (junkbuff);
  775.             return (RHexit);
  776.             }
  777.  
  778.         if (i != 0xff)
  779.             {
  780.             if (args->timer2 == 0L)
  781.                args->timer2 = timerset (1000);
  782.             return (RH3);
  783.             }
  784.         }
  785.     return (RH5);
  786. }
  787. /*
  788.  .-----+----------+-------------------------+-------------------------+-----.
  789.  | RH3 | TossJunk | 10 sec timer expires    | Too much noise          | RH4 |
  790.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  791.  |     |          | Received Hex 1f         | Got header, get packet  | RH5 |
  792.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  793.  |     |          | Input buffer empty      | Try to resynch          | RH4 |
  794.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  795.  |     |          | Carrier lost            | Report failure          | exit|
  796.  `-----+----------+-------------------------+-------------------------+-----'
  797. */
  798. int RHTossJunk (YHARGSP args)
  799. {
  800.     while (!timeup (args->timer2))
  801.         {
  802.         if (got_ESC ())
  803.             {
  804.             status_line (MSG_TXT(M_KBD_MSG));
  805.             return (RHexit);
  806.             }
  807.  
  808.         if (!CHAR_AVAIL ())
  809.             return (RH4);
  810.  
  811.         if (TIMED_READ (0) == 0x1f)
  812.             return (RH5);
  813.  
  814.         if (!CARRIER)
  815.             {
  816.             status_line (MSG_TXT(M_NO_CARRIER));
  817.             return (RHexit);
  818.             }
  819.         }
  820.     return (RH4);
  821. }
  822. /*
  823.  .-----+----------+-------------------------+-------------------------+-----.
  824.  | RH4 | ReSynch  |                         | Clear input buffer      | RH2 |
  825.  |     |          |                         | Send ENQ                |     |
  826.  `-----+----------+-------------------------+-------------------------+-----'
  827. */
  828. int RHReSynch (YHARGSP args)
  829. {
  830.     CLEAR_INBOUND ();
  831.     SENDBYTE (ENQ);
  832.     args->timer2 = 0L;
  833.     return (RH2);
  834. }
  835. /*
  836.  .-----+----------+-------------------------+-------------------------+-----.
  837.  | RH5 | HdrSetup |                         | Initialize CRC          |     |
  838.  |     |          |                         | Set 30 second timer     | RH6 |
  839.  `-----+----------+-------------------------+-------------------------+-----'
  840. */
  841. int RHHdrSetup (YHARGSP args)
  842. {
  843.     (void) memset ((char *) &args->Hello, 0, sizeof (struct _Hello));
  844.     args->crc = args->count = 0;
  845.     args->timer3 = timerset (3000);
  846.     return (RH6);
  847. }    
  848. /*
  849.  .-----+----------+-------------------------+-------------------------+-----.
  850.  | RH6 | GetHChar | 30 sec timer expires or |                         |     |
  851.  |     |          | carrier lost            | Report failure          | exit|
  852.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  853.  |     |          | Character received      | Process character       | RH7 |
  854.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  855.  |     |          | 10 seconds with no char | Error, try resync       | RH9 |
  856.  `-----+----------+-------------------------+-------------------------+-----'
  857. */
  858. int RHGetHChar (YHARGSP args)
  859. {
  860.     long localtimer;
  861.     char junkbuff [80];
  862.  
  863.     localtimer = timerset (1000);
  864.  
  865.     while (PEEKBYTE () < 0)
  866.         {
  867.         if (timeup (args->timer3))
  868.             {
  869.             (void) sprintf (junkbuff, "!%s",MSG_TXT(M_TIMEOUT));
  870.             status_line (junkbuff);
  871.             return (RHexit);
  872.             }
  873.  
  874.         if (timeup (localtimer))
  875.             return (RH9);
  876.       
  877.         if (got_ESC ())
  878.             {
  879.             status_line (MSG_TXT(M_KBD_MSG));
  880.             return (RHexit);
  881.             }
  882.  
  883.         if (!CARRIER)
  884.             {
  885.             status_line (MSG_TXT(M_NO_CARRIER));
  886.             return (RHexit);
  887.             }
  888.  
  889.        time_release ();
  890.        }
  891.     return (RH7);
  892. }
  893. /*
  894.  .-----+----------+-------------------------+-------------------------+-----.
  895.  | RH7 | StoHChar | Buffer and CRC filled   | Compare CRC             | RH8 |
  896.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  897.  |     |          | More characters needed  | Reset 30 sec timer      | RH6 |
  898.  `-----+----------+-------------------------+-------------------------+-----'
  899. */
  900. int RHStoHChar (YHARGSP args)
  901. {
  902.     int c;
  903.     int i;
  904.     char *sptr = (char *)&(args->Hello);
  905.  
  906.     while (PEEKBYTE () >= 0)
  907.         {
  908.         c = TIMED_READ (0);
  909.         switch (i = args->count)
  910.             {
  911.             case 128:
  912.             args->hiscrc = c << 8;
  913.             args->count++;
  914.             break;
  915.  
  916.             case 129:
  917.             args->hiscrc += c;
  918.             return (RH8);
  919.  
  920.             default:
  921.             sptr [i] = (char)c;
  922.             args->crc = xcrc (args->crc, (byte) c);
  923.             args->count++;
  924.             break;
  925.             }
  926.         }
  927.     args->timer3 = timerset (3000);
  928.     return (RH6);
  929. }
  930. /*
  931.  .-----+----------+-------------------------+-------------------------+-----.
  932.  | RH8 | CheckCRC | CRC matches             | Finish Receive          | RH10|
  933.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  934.  |     |          | CRC doesn't match       | Handle error            | RH9 |
  935.  `-----+----------+-------------------------+-------------------------+-----'
  936. */
  937. int RHCheckCRC (YHARGSP args)
  938. {
  939.     char junkbuff [80];
  940.  
  941.     if (args->crc == args->hiscrc)
  942.         return (RH10);
  943.  
  944.     (void) sprintf (junkbuff, "!%s", MSG_TXT(M_CRC_MSG));
  945.     status_line (junkbuff);
  946.     return (RH9);
  947. }
  948. /*
  949.  .-----+----------+-------------------------+-------------------------+-----.
  950.  | RH9 | CountERR | Less than 10 errors     | Send '?' (0x3f)         | RH2 |
  951.  |     |          +- - - - - - - - - - - - -+- - - - - - - - - - - - -+- - -|
  952.  |     |          | 10 errors               | Hang up, report failure | exit|
  953.  `-----+----------+-------------------------+-------------------------+-----'
  954. */
  955. int RHCountERR (YHARGSP args)
  956. {
  957.     if ((args->retries++) < 10)
  958.         {
  959.         CLEAR_INBOUND ();
  960.         SENDBYTE ('?');
  961.         return (RH2);
  962.         }
  963.  
  964.     status_line (MSG_TXT(M_FUBAR_MSG));
  965.     return (RHexit);
  966. }
  967. /*
  968.  .-----+----------+-------------------------+-------------------------+-----.
  969.  | RH10| HelloOK  |                         | Clear inbound buffer    | exit|
  970.  |     |          |                         | Send ACK                |     |
  971.  `-----+----------+-------------------------+-------------------------+-----'
  972. */
  973. int RHHelloOK (YHARGSP args)
  974. {
  975.     char *p;
  976.     char junkbuff [128];
  977.     ADDR his_boss;
  978.     int j;
  979.  
  980.    /* The idea for removing junk characters came from Holger Schurig */
  981.    /* Get rid of junk characters */
  982.  
  983.     for (p = args->Hello.my_name; *p != '\0'; p++)
  984.         if (*p < ' ')
  985.             *p = ' ';
  986.  
  987.    /* Get rid of junk characters */
  988.  
  989.     for (p = args->Hello.sysop; *p != '\0'; p++)
  990.         if (*p < ' ')
  991.             *p = ' ';
  992.  
  993.     remote_addr.Zone = args->Hello.my_zone;
  994.     remote_addr.Net = args->Hello.my_net;
  995.     remote_addr.Node = args->Hello.my_node;
  996.     remote_addr.Point = args->Hello.my_point;
  997.  
  998.     if ((args->Hello.capabilities & DO_DOMAIN) && (my_addr.Domain != NULL))
  999.         {
  1000.         remote_addr.Domain = find_domain (&(args->Hello.my_name[strlen (args->Hello.my_name) + 1]));
  1001.         }
  1002.     else
  1003.         remote_addr.Domain = NULL;
  1004.  
  1005.  
  1006.     if (strlen (args->Hello.my_name) > 42)
  1007.         args->Hello.my_name[42] = '\0';
  1008.  
  1009.     args->Hello.sysop[19] = '\0';
  1010.  
  1011.     remote_capabilities = args->Hello.capabilities;
  1012.  
  1013.     his_boss = remote_addr;
  1014.     his_boss.Point = 0;
  1015.  
  1016.     if (nodefind (&his_boss, 0) && !remote_addr.Zone)
  1017.         remote_addr.Zone = found_zone;
  1018.  
  1019.     (void) sprintf (junkbuff, "*%s (%s)",
  1020.              args->Hello.my_name,
  1021.              Full_Addr_Str (&remote_addr));
  1022.     status_line (junkbuff);
  1023.  
  1024.     if ((pvtnet >= 0) &&
  1025.         ((remote_addr.Zone == alias[assumed].Zone) || (remote_addr.Zone == 0)) &&
  1026.         (remote_addr.Net == boss_addr.Net) && (remote_addr.Node == boss_addr.Node) &&
  1027.         (remote_addr.Point > 0))
  1028.         {
  1029.         remote_addr.Net = pvtnet;
  1030.         remote_addr.Node = args->Hello.my_point;
  1031.         remote_addr.Point = 0;
  1032.         }
  1033.  
  1034.     log_product (args->Hello.product, args->Hello.product_maj, args->Hello.product_min);
  1035.  
  1036. #ifdef MILQ
  1037.     if (isMILQUE == args->Hello.product)
  1038.         {
  1039.         UsePaths = TRUE;
  1040.         status_line (" Paths Will Be Used");
  1041.         }
  1042. #endif
  1043.  
  1044.     if (args->Hello.sysop[0])
  1045.         status_line (":Sysop: %s", args->Hello.sysop);
  1046.  
  1047.     if ((pvtnet >= 0) && (remote_addr.Point > 0))
  1048.         {
  1049.         remote_addr.Point = 0;
  1050.         remote_addr.Node = (unsigned int) -1;
  1051.         }
  1052.  
  1053.     if (n_getpassword (&remote_addr))
  1054.         {
  1055.         if ((j = n_password ((char *)args->Hello.my_password, remote_password)) != 0)
  1056.             {
  1057.             if ((j == 1) || ((j == 2) && (args->sender == 0)))
  1058.                 {
  1059.                 LOWER_DTR ();                          /* He'll never get it right */
  1060.                 timer (2);                             /* Wait two secs */
  1061.                 return (RHexit);
  1062.                 }
  1063.             else
  1064.                 {
  1065.                 status_line (MSG_TXT(M_PASSWORD_OVERRIDE));
  1066.                 }
  1067.             }
  1068.         }
  1069.  
  1070.     CLEAR_INBOUND ();
  1071.     SENDBYTE (ACK);
  1072.  
  1073.     args->result = 1;
  1074.     return (RHexit);
  1075. }
  1076.